package zhongbo.java.air.fightpath.service.Impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import zhongbo.java.air.common.vo.PageVo;
import zhongbo.java.air.fightpath.excption.ArchiveException;
import zhongbo.java.air.fightpath.excption.ExceptionCode;
import zhongbo.java.air.fightpath.listener.RedisLogChanelPublisher;
import zhongbo.java.air.fightpath.mapper.FlightMapper;
import zhongbo.java.air.fightpath.model.FlightPath;
import zhongbo.java.air.fightpath.service.IAirFightPathService;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
public class AirFightPathServiceImpl implements IAirFightPathService {
    @Autowired
    private RedisLogChanelPublisher publisher;

    @Autowired
    private FlightMapper flightMapper;

    @Override
    public FlightPath add(FlightPath path) {
        path.setTimestamp(new Date());
//        validFightPath(path);

        int insert = flightMapper.insert(path);
        if (insert > 0) {
            // 发布日志
            publisher.sendMessage(
                    String.format("创建航班轨迹 %s (%s->%s)",
                            path.getSourceType(),
                            path.getIcaoCode(),
                            path.getTimestamp())
            );
            return path;

        }

        throw new RuntimeException("新增航跡失败");
    }

    /**
     * 验证信息
     *
     * @param path 飞机轨迹实体
     */
    private void validFightPath(FlightPath path) {
        if (path == null) {
            throw new RuntimeException("飞机信息不能为空");
        }
        List<FlightPath> fightPaths = flightMapper.selectList(null);
        Date timestamp = path.getTimestamp();
        if (timestamp == null) {
            throw new RuntimeException("时间戳不能为空");
        }
        for (FlightPath fightPath : fightPaths) {
            if (timestamp == fightPath.getTimestamp()) {
                throw new RuntimeException("时间戳不能重复");
            }
        }


        String code = path.getIcaoCode();
        if (code.length() > 6) {
            throw new RuntimeException("ICAO不能不能超过6个字段");
        }

        for (FlightPath fightPath : fightPaths) {
            //ICAO唯一的
            if (Objects.equals(code, fightPath.getIcaoCode())) {
                throw new RuntimeException("ICAO唯一的");
            }
        }
    }

    @Override
    public String delete(String id) {

        if (StrUtil.isBlank(id)) {
            throw new ArchiveException(ExceptionCode.NOT_BE_EMPTY);
        }
        int delete = flightMapper.deleteById(id);
        if (delete > 0) {
            publisher.sendMessage(
                    "删除航班轨迹" + id
            );
            return id;
        }


        throw new ArchiveException(ExceptionCode.CANNOT_BE_DELETE);
    }

    @Override
    public FlightPath edit(FlightPath path1) {
        validFightPath(path1);

        path1.setTimestamp(new Date());
        String id = path1.getId();
        if (StrUtil.isBlank(id)) {
            throw new ArchiveException(ExceptionCode.NOT_BE_EMPTY);
        }
        FlightPath craft = flightMapper.selectById(id);
        if (craft == null) {
            throw new ArchiveException(ExceptionCode.CANNOT_BE_MODIFIED);
        }
        int update = flightMapper.updateById(path1);
        if (update > 0) {
            publisher.sendMessage(
                    String.format("修改航班轨迹 %s (%s->%s)",
                            path1.getSourceType(),
                            path1.getIcaoCode(),
                            path1.getTimestamp())
            );
            return path1;
        }

        throw new RuntimeException("修改飞机失败");
    }

    @Override
    public FlightPath findOne(String id) {
        if (StrUtil.isBlank(id)) {
            throw new ArchiveException(ExceptionCode.NOT_BE_EMPTY);
        }
        FlightPath path = flightMapper.selectById(id);
        if (path == null) {
            throw new ArchiveException(ExceptionCode.CANNOT_BE_QUERY);
        } else {
            publisher.sendMessage(
                    "寻找航班轨迹" + id
            );
            return path;
        }
    }


    /**
     * //     * @param endTime   示例 2025-04-05 06:48:52
     * //     * @param startTime 示例 2025-04-03 06:48:52
     */
    @Override
    public PageVo<FlightPath> findPage(String keyword, String fields,
                                       String icaoCode
            , String endTime, String startTime,
                                       Integer pageNumber, Integer pageSize,
                                       String oderByField, Boolean oderByAsc) {
        QueryWrapper<FlightPath> queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(icaoCode)) {
            queryWrapper.eq("icao_code", icaoCode);
        }
        if (StrUtil.isNotBlank(endTime)) {
            queryWrapper.le("timestamp", endTime);
        }
        if (StrUtil.isNotBlank(startTime)) {
            queryWrapper.ge("timestamp", startTime);
        }
        //检测是否有排序
        //支持指定字段模糊搜索Keyword
        if (StrUtil.isNotBlank(keyword) && StrUtil.isNotBlank(fields)) {
            String[] fieldsArray = fields.split(",");
            for (String field : fieldsArray) {
                queryWrapper.like(StrUtil.toUnderlineCase(field), keyword);
            }

        }
        if (StrUtil.isNotBlank(oderByField)) {
            //检测是正序还是倒序
            boolean isOderByAsc = Boolean.TRUE.equals(oderByAsc);
            if (isOderByAsc) {
                //正
                queryWrapper.orderByAsc(oderByField);
            } else {
                //倒序
                queryWrapper.orderByAsc(oderByField);
            }
        }
        Page<FlightPath> pageParam = new Page<>(pageNumber, pageSize);
        Page<FlightPath> airPage = flightMapper.selectPage(pageParam, queryWrapper);

        return new PageVo<>(airPage);
    }
}
